﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;
using IniParser;
using IniParser.Model;
using WpfApp3.Models;



/*
 ini文件
   结构特点
   文本格式，由节（Section）、键值对（Key-Value）和注释（; 或 # 开头）组成。
   节用方括号 [SectionName] 标识，键值对格式为 Key=Value

如

[Database]
Server=localhost
Port=3306
Username=admin
Password=123456

[Settings]
DebugMode=true
LogPath=C:\logs\app.log


 一，手动解析（基础实现）
二，使用 P/Invoke 调用 Windows API
三，使用第三方库（IniParser）

 */
namespace WpfApp3.Data_Operations
{
    public class Fileoperation_ini
    {

        // INI 文件解析器核心对象
        private readonly FileIniDataParser _parser;
        // INI 文件数据模型（内存中的INI结构）
        private IniData _iniData;
        // 存储文件路径
        private readonly string _filePath;
        // 固定节名（用于存放所有Person数据），可以用id作为键名
        private const string PERSON_SECTION = "Persons";



        public Fileoperation_ini(string filePath)
        {
            // 初始化解析器
            _parser = new FileIniDataParser();
            // 记录文件路径
            _filePath = filePath;
            // 确保存储目录存在
            EnsureDirectoryExists();
            // 加载或初始化 INI 数据
            LoadOrInitializeIniData();
        }

        private void EnsureDirectoryExists()
        {
            // 获取文件所在目录路径
            string directory = Path.GetDirectoryName(_filePath);
            // 若目录不存在则创建
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
        }

        private void LoadOrInitializeIniData()
        {
            try
            {
                // 若文件存在则加载，否则创建新的INI数据模型
                if (File.Exists(_filePath))
                {   //模型加载初始化
                    _iniData = _parser.ReadFile(_filePath);
                }
                else
                {
                    // 初始化空的INI数据，并创建Persons节
                    _iniData = new IniData();
                    _iniData.Sections.AddSection(PERSON_SECTION);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载INI文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                // 初始化空数据作为降级处理

                //降级处理（Graceful Degradation），即在发生错误时确保程序不会崩溃，而是进入一个安全状态继续运行
                //_iniData = new IniData();
                //_iniData.Sections.AddSection(PERSON_SECTION);

                //不方便学习和调试没有必要 
            }
        }

        public void WritePerson(Person person)
        {
            // 验证参数
            if (person == null )
            {
                throw new ArgumentException("Person对象或姓名不能为空", nameof(person));
            }

            try
            {
                // 将Person属性序列化为字符串 格式|分离，格式不重要只是一种存储方式
                string value = $"{person.Age}|{person.Gender}|{person.Characteristics}|{person.Political}|{person.Marital}|{person.Remarks}";

                // 以姓名作为键，存储到Persons节中
                _iniData[PERSON_SECTION][person.Name] = value;
                //_iniData：是内存中的数据结构（如 Dictionary），程序运行时可随时修改
                //INI 文件：是磁盘上的文本文件，程序关闭后数据依然存在
                //所以需要将_iniData写入ini文件

                //实际存储name=value这是个键对
                // 写入文件（持久化）一个叫做_parser的文件操作对象，的一个写入文件方法，传写入模型（_iniData），写到什么文件
                _parser.WriteFile(_filePath, _iniData);
                MessageBox.Show("ini添加成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"写入Person到INI失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        /// <summary>
        /// 一个读取文件数据的基方法，在getall中反复调用
        /// </summary>
        /// <param name="ReadPerson"></param>
        public Person ReadPerson(string name)
        {
            // 验证参数
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("姓名不能为空", nameof(name));
            }

            try
            {
                // 检查键是否存在            
                if (!_iniData[PERSON_SECTION].ContainsKey(name))
                {
                    return null; // 未找到返回null
                }

                // 读取存储的字符串并按照写入时的格式拆分
                string[] parts = _iniData[PERSON_SECTION][name].Split('|');

                // 解析为Person对象（注意：数组长度需与序列化时一致）
                return new Person
                {
                    Name = name,
                    Age = parts.Length > 0 ? int.TryParse(parts[0], out int age) ? age : 0 : 0,
                    Gender = parts.Length > 1 ? parts[1] : string.Empty,
                    Characteristics = parts.Length > 2 ? parts[2] : string.Empty,
                    Political = parts.Length > 3 ? parts[3] : string.Empty,
                    Marital = parts.Length > 4 ? parts[4] : string.Empty,
                    Remarks = parts.Length > 5 ? parts[5] : string.Empty
                };
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取Person from INI失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return null;
            }
        }


        //因为getall功能在sqlite数据库中已经全部读取，只作为学习方法没有引用
        public List<Person> ReadAllPersons()
        {
            var persons = new List<Person>();
            try
            {
                // 遍历Persons节中的所有键值对
                foreach (var keyValue in _iniData[PERSON_SECTION])
                {
                    // 调用单个读取方法解析
                    var person = ReadPerson(keyValue.KeyName);
                    if (person != null)
                    {
                        persons.Add(person);
                    }
                }
                return persons;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取所有Person失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return null;
            }
        }

        public bool DeletePerson(string name)
        {// 检查是否存在
            if (string.IsNullOrWhiteSpace(name))
            {
                return false;
            }

            try
            {
                // 检查键是否存在
                if (!_iniData[PERSON_SECTION].ContainsKey(name))
                {
                    return false; // 键不存在，无需删除
                }

                // 从节中移除键
                _iniData[PERSON_SECTION].RemoveKey(name);

                // 加载到文件
                _parser.WriteFile(_filePath, _iniData);
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除Person失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
        }


        public void ClearAll()
        {
            try
            {
                // 清空指定节中的所有键值对
                _iniData[PERSON_SECTION].RemoveAllKeys();
               
                // 加载到文件
                _parser.WriteFile(_filePath, _iniData);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"清空INI数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

       
    }
}
